using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using UnityEngine;

namespace IQIGame.Onigao.Game
{
    public class Entity : IPoolObject
    {
        public int Id { get; private set; }
        public string AssetName { get; set; }
        public EntityGroup EntityGroup { get; private set; }
        public float LastUseTime => m_LastUseTime;
        public GameObject gameObject { get; private set; }
        public Transform transform { get; private set; }
        protected ResLoader loader { get; private set; }
        /// <summary>
        /// ClassPool（引用池，主要管理引用） MaxScore
        /// Entity类实例的最大数量，不是ObjectPoolManager.ObjectPool（资源对象池，主要管理资源）的最大数量
        /// 当ObjectPoolManager超过Capacity时，仍然可以创建Entity，只是不进池，此时Entity的引用依然可以通过引用池重用，由于引用的内存要小得多，所以通常允许的数量也比ObjectPool的TotalCapacity大
        /// </summary>
        /// <returns></returns>
        public uint MaxStore => 30;     //改成固定值，最多存30足矣
        public bool isLoading { get; private set; }
        public bool isLoaded => gameObject != null;

        private float m_LastUseTime;

        #region ILinkedListNode
        ILinkedListNode ILinkedListNode.Next { get; set; }
        ILinkedListNode ILinkedListNode.Previous { get; set; }
        #endregion

        /// <summary>
        /// 实体初始化，仅创建时调用。
        /// </summary>
        /// <param name="gameObject">实体GameObject。</param>
        public virtual void OnInit(string assetName)
        {
            this.AssetName = assetName;
            this.loader = ResLoader.Create();
        }

        public void SetGroup(EntityGroup entityGroup)
        {
            EntityGroup = entityGroup;
        }

        public void SetId(int entityId)
        {
            Id = entityId;
        }

        public async UniTask<EntityLoadState> Load()
        {
            if (isLoaded)
                return EntityLoadState.CompleteFromPool;
            isLoading = true;
            GameObject prefab = await loader.LoadABAssetAwait<GameObject>(AssetName);
            if (prefab == null)
            {
                isLoading = false;
                return EntityLoadState.Error;
            }
            this.gameObject = Object.Instantiate(prefab);
            this.transform = gameObject.transform;
            isLoading = false;
            OnLoadComplete();
            return EntityLoadState.CompleteByLoad;
        }

        public bool CancelLoading()
        {
            if (!isLoading)
            {
                return false;
            }
            isLoading = false;
            loader.ReleaseAllRes();
            return true;
        }

        public virtual void OnUpdate(float deltaTime, float unScaledDeltaTime)
        {

        }

        /// <summary>
        /// 从池里取出
        /// </summary>
        public virtual void OnGetFromPool()
        {
            if (isLoaded)
            {
                gameObject.SetActive(true);
            }
            m_LastUseTime = Time.realtimeSinceStartup;
        }

        public virtual void OnLoadComplete()
        {

        }

        /// <summary>
        /// 返回对象池(注意这个对象池是DisplayObject的对象池，不是ClassPool)
        /// </summary>
        public virtual void OnPutBackToPool()
        {
            if (isLoaded)
            {
                gameObject.SetActive(false);
            }
            Clear();
        }

        /// <summary>
        /// 清理实例数据，如id，使用时间等，但不能清理基础数据
        /// 放回对象池时调用
        /// </summary>
        private void Clear()
        {
            m_LastUseTime = default;
            Id = 0;
        }

        /// <summary>
        /// ClassPool Func clear
        /// </summary>
        public void OnReset()
        {
            Clear();
            Object.Destroy(gameObject);
            loader?.Put2Pool();
            loader = null;
            gameObject = null;
            transform = null;
            AssetName = null;
            EntityGroup = null;
            isLoading = false;
        }
    }
}
